#pragma once
#include "sstream.h"
using namespace std;

#define Tnline template<typename T> inline

class Insert
{
private:
	string _table;
	sstream _names;
	sstream _values;
public:
	inline Insert(const string&);
	inline Insert& clear(void);
	inline Insert& operator>>(const string& s);
	Tnline Insert& operator<<(T v);
public:
	inline string names(void)const;
	inline string values(void)const;
	inline string data(void)const;
};

inline Insert::Insert(const string& s):_table(s)
{
}
inline Insert& Insert::clear(void)
{
	_names.str("");
	_values.str("");
	return *this;
}
inline Insert& Insert::operator>>(const string& s)
{
	if(_names.tellp() > 0)
	{
		_names << ",";
	}
	_names << s;
	return *this;
}
inline string Insert::names(void)const
{
	if( ((Insert*)this)->_names.tellp())
	{
		return " (" + _names.str() + ")";
	}
	return "";
}
inline string Insert::values(void)const
{
	if( ((Insert*)this)->_values.tellp())
	{
		return " VALUES (" + _values.str() + ");";
	}
	return "";
}
inline string Insert::data(void)const
{
	return "INSERT INTO " + _table + names() + values();
}

Tnline Insert& Insert::operator<<(T v)
{
	if(_values.tellp() > 0)
	{
		_values << ",";
	}
	_values << "'" << v << "'";
	return *this;
}
template<> inline Insert& Insert::operator<<(const char v)
{
	return *this << int(v);
}
template<> inline Insert& Insert::operator<<(const signed char v)
{
	return *this << int(v);
}
template<> inline Insert& Insert::operator<<(const unsigned char v)
{
	return *this << int(v);
}
#undef Tnline
